package com.beiing.leafchat;


import com.beiing.leafchat.bean.Axis;
import com.beiing.leafchat.bean.AxisValue;
import com.beiing.leafchat.bean.ChartData;
import com.beiing.leafchat.bean.PointValue;
import com.beiing.leafchat.renderer.AbsRenderer;
import com.beiing.leafchat.support.Chart;
import com.beiing.leafchat.support.LeafUtil;
import com.beiing.leafchat.support.Mode;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.app.Context;

import java.util.List;

/**
 * Created by chenliu on 2016/7/15.<br/>
 * 描述：
 * </br>
 */
public abstract class AbsLeafChart extends Component implements Chart, Component.DrawTask {

    static final String TAG = SlideSelectLineChart.class.getName();

    /**
     * 坐标轴相交模式
     */
    protected int coordinateMode = Mode.INTERSECT;

    /**
     * 第一个点x轴方向起始位置
     */
    protected int startMarginX = 0;
    /**
     * 第一个点y轴方向起始位置
     */
    protected int startMarginY = 0;

    protected Axis axisX;
    protected Axis axisY;

    protected int mWidth;//控件宽度
    protected int mHeight;//控件高度
    protected int leftPadding, topPadding, rightPadding, bottomPadding;//控件内部间隔

    protected Context mContext;

    private AbsRenderer absRenderer;

    public AbsLeafChart(Context context) {
        this(context, null, "0");
    }

    public AbsLeafChart(Context context, AttrSet attrs) {
        this(context, attrs, "0");
    }

    public AbsLeafChart(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initRenderer();
        setRenderer();
        initAttrs(attrs);

        initViewSize();
        resetAsixSize();
        resetPointWeight();
    }

    protected void initAttrs(AttrSet attrs) {
        leftPadding = (int) LeafUtil.dp2px(mContext, 20);
        topPadding = (int) LeafUtil.dp2px(mContext, 10);
        rightPadding = (int) LeafUtil.dp2px(mContext, 10);
        bottomPadding = (int) LeafUtil.dp2px(mContext, 20);
        startMarginX = 0;
        startMarginY = 0;
        try {
            String lc_coordinateMode = attrs.getAttr("lc_coordinateMode").get().getStringValue();
            switch (lc_coordinateMode) {
                case "intersect":
                    coordinateMode = Mode.INTERSECT;
                    break;
                case "across":
                    coordinateMode = Mode.ACROSS;
                    break;
                case "x_across":
                    coordinateMode = Mode.X_ACROSS;
                    break;
                case "y_across":
                    coordinateMode = Mode.Y_ACROSS;
                    break;
            }
        } catch (Exception e) {
        }
//        try {
//            leftPadding= attrs.getAttr("lc_leftPadding").get().getFloatValue();
//        }catch (Exception e){}
//        try {
//            topPadding= attrs.getAttr("lc_topPadding").get().getFloatValue();
//        }catch (Exception e){}
//        try {
//            rightPadding= attrs.getAttr("lc_rightPadding").get().getFloatValue();
//        }catch (Exception e){}
//        try {
//            bottomPadding= attrs.getAttr("lc_bottomPadding").get().getFloatValue();
//        }catch (Exception e){}
//        try {
//            startMarginX= attrs.getAttr("lc_startMarginX").get().getIntegerValue();
//        }catch (Exception e){}
//        try {
//            startMarginY= attrs.getAttr("lc_startMarginY").get().getIntegerValue();
//        }catch (Exception e){}

    }

    public void setRenderer(AbsRenderer renderer) {
        this.absRenderer = renderer;
    }

    ///////////////////子类必须重写的方法////////////////////////////
    protected abstract void initRenderer();

    protected abstract void setRenderer();

    protected abstract void resetPointWeight();

//    /**
//     * 不重写改方法，在布局中使用 wrap_content 显示效果是 match_parent
//     *
//     * @param widthMeasureSpec
//     * @param heightMeasureSpec
//     */
//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
//        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
//        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//
//        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
//            setMeasuredDimension((int) LeafUtil.dp2px(mContext, 300), (int) LeafUtil.dp2px(mContext, 300));
//        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
//            setMeasuredDimension((int) mWidth, heightSpecSize);
//        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
//            setMeasuredDimension(widthSpecSize, (int) mHeight);
//        }
//
//    }


    protected void initViewSize() {
        mWidth = 1080;
        mHeight = getHeight();
        absRenderer.setWH(mWidth, mHeight);
        absRenderer.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
    }

    /**
     * 设置坐标轴位置
     */
    public void resetAsixSize() {

        resetAsixX();

        resetAsixY();

    }

    protected void resetAsixY() {
        if (axisY != null) {
            List<AxisValue> values = axisY.getValues();
            int sizeY = values.size(); //几条x轴
            float yStep =(float) (mHeight - topPadding - bottomPadding - startMarginY) / sizeY;
            for (int i = 0; i < sizeY; i++) {
                AxisValue axisValue = values.get(i);
                axisValue.setPointX(leftPadding);
                if (i == 0) {
                    axisValue.setPointY(mHeight - bottomPadding - startMarginY);
                } else {
                    axisValue.setPointY(mHeight - bottomPadding - startMarginY - (int) LeafUtil.mul(yStep, i));
                }
            }
            switch (coordinateMode) {
                case Mode.ACROSS:
                case Mode.Y_ACROSS:
                    axisY.setStartY(mHeight - (int) (bottomPadding * 0.5f));
                    break;

                case Mode.INTERSECT:
                case Mode.X_ACROSS:
                    axisY.setStartY(mHeight - bottomPadding);
                    break;
            }
            axisY.setStartX(leftPadding).setStopX(leftPadding).setStopY(0);
        }
    }

    protected void resetAsixX() {
        if (axisX != null) {
            List<AxisValue> values = axisX.getValues();
            int sizeX = values.size(); //几条y轴
            float xStep =(float) (mWidth - leftPadding - startMarginX) / sizeX;
            for (int i = 0; i < sizeX; i++) {
                AxisValue axisValue = values.get(i);
                axisValue.setPointY(mHeight);
                if (i == 0) {
                    axisValue.setPointX(leftPadding + startMarginX);
                } else {
                    axisValue.setPointX(leftPadding + startMarginX + (int) LeafUtil.mul(xStep, i));
                }
            }


            switch (coordinateMode) {
                case Mode.ACROSS:
                case Mode.X_ACROSS:
                    axisX.setStartX(LeafUtil.mul(leftPadding, 0.5f));
                    break;

                case Mode.INTERSECT:
                case Mode.Y_ACROSS:
                    axisX.setStartX(leftPadding);
                    break;
            }
            axisX.setStartY(mHeight - bottomPadding).setStopX(mWidth).setStopY(mHeight - bottomPadding);
        }
    }


    @Override
    public void onDraw(Component component, Canvas canvas) {
        absRenderer.drawCoordinateLines(canvas, axisX, axisY);
        absRenderer.drawCoordinateText(canvas, axisX, axisY);
    }


    protected void resetPointWeight(ChartData chartData) {
        if (chartData != null && axisX != null && axisY != null) {
            List<PointValue> values = chartData.getValues();
            int size = values.size();
            List<AxisValue> axisValuesX = axisX.getValues();
            List<AxisValue> axisValuesY = axisY.getValues();
            float totalWidth = Math.abs(LeafUtil.add(axisValuesX.get(0).getPointX(), -axisValuesX.get(axisValuesX.size() - 1).getPointX()));

            float totalHeight = Math.abs(LeafUtil.add(axisValuesY.get(0).getPointY(), -axisValuesY.get(axisValuesY.size() - 1).getPointY()));
            for (int i = 0; i < size; i++) {
                PointValue pointValue = values.get(i);
                int diffX = (int) LeafUtil.mul(pointValue.getX(), totalWidth);
                pointValue.setDiffX(diffX);

                int diffY = (int) LeafUtil.mul(pointValue.getY(), totalHeight);
                pointValue.setDiffY(diffY);

                float originX1 = diffX + leftPadding + startMarginX;
                float originY1 = mHeight - bottomPadding - diffY - startMarginY;
                pointValue.setOriginX(originX1).setOriginY(originY1);

            }
        }
    }

    @Override
    public void setAxisX(Axis axisX) {
        this.axisX = axisX;
        resetAsixX();
        invalidate();
    }

    @Override
    public void setAxisY(Axis axisY) {
        this.axisY = axisY;
        resetAsixY();
        invalidate();
    }

    @Override
    public Axis getAxisX() {
        return axisX;
    }

    @Override
    public Axis getAxisY() {
        return axisY;
    }

//    @Override
//    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
//        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
//        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
//        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//        if (widthSpecMode == MeasureSpec.PRECISE && heightSpecMode == MeasureSpec.PRECISE) {
//            setEstimatedSize((int) LeafUtil.dp2px(mContext, 300), (int) LeafUtil.dp2px(mContext, 300));
//        } else if (widthSpecMode == MeasureSpec.PRECISE) {
//            setEstimatedSize((int) mWidth, heightSpecSize);
//        } else if (heightSpecMode == MeasureSpec.PRECISE) {
//            setEstimatedSize(widthSpecSize, (int) mHeight);
//        }
//
//
//        return false;
//    }
}
